package com.fastjars.business.upload.hunter;

import com.fastjars.business.upload.ActionResult;
import com.fastjars.business.upload.ActionState;
import com.fastjars.business.upload.PathFormat;
import com.fastjars.business.upload.ResourceUploader;
import org.springframework.web.util.HtmlUtils;

import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * ImageHunter
 *
 * @author Brant Liu <br> 邮箱：<br>lbf1988@qq.com <br>日期：<br>2018/04/17
 * @version 1.0.0
 */
public class ImageHunter {
    public static final Map<String, String> imageMimes = new HashMap<String, String>();
    static {
        imageMimes.put("image/gif", ".gif");
        imageMimes.put("image/jpeg", ".jpg");
        imageMimes.put("image/jpg", ".jpg");
        imageMimes.put("image/png", ".png");
        imageMimes.put("image/bmp", ".bmp");
    };

    private String filename = null;
    private String savePath = null;
    private String rootPath = null;
    private List<String> allowTypes = null;
    private long maxSize = -1;

    private List<String> filters = null;

    public ImageHunter(Map<String, Object> conf) {
        this.filename = (String) conf.get("filename");
        this.savePath = (String) conf.get("savePath");
        this.rootPath = (String) conf.get("rootPath");
        this.maxSize = (Long) conf.get("maxSize");
        this.allowTypes = Arrays.asList((String[]) conf.get("allowFiles"));
        this.filters = Arrays.asList((String[]) conf.get("filter"));
    }

    public ActionResult capture(String[] list) {
        ActionResult state = new ActionResult(ActionState.SUCCESS);
        for (String source : list) {
            state.addItem(captureRemoteData(source));
        }
        return state;
    }

    public ActionResult captureRemoteData(String urlStr) {
        HttpURLConnection connection = null;
        URL url = null;
        String suffix = null;
        try {
            url = new URL(urlStr);
            if (!validHost(url.getHost())) {
                return new ActionResult(ActionState.PREVENT_HOST);
            }
            connection = (HttpURLConnection) url.openConnection();

            connection.setInstanceFollowRedirects(true);
            connection.setUseCaches(true);

            if (!validContentState(connection.getResponseCode())) {
                return new ActionResult(ActionState.CONNECTION_ERROR);
            }
            suffix = imageMimes.get(connection.getContentType().toLowerCase());
            if (!validFileType(suffix)) {
                return new ActionResult(ActionState.NOT_ALLOW_FILE_TYPE);
            }
            if (!validFileSize(connection.getContentLength())) {
                return new ActionResult(ActionState.MAX_SIZE);
            }
            String savePath = this.getPath(this.savePath, this.filename, suffix);
            String physicalPath = this.rootPath + savePath;
            ActionResult state = ResourceUploader.saveFileByInputStream(connection.getInputStream(), physicalPath);
            if (ActionState.getStateInfo(ActionState.SUCCESS).equals(state.getState())) {
                state.setUrl(PathFormat.format(savePath));
                state.setSource(HtmlUtils.htmlUnescape(urlStr));
            }
            return state;
        } catch (Exception e) {
            return new ActionResult(ActionState.REMOTE_FAIL);
        }
    }

    private String getPath(String savePath, String filename, String suffix) {
        return PathFormat.parse(savePath + suffix, filename);
    }

    private boolean validHost(String hostname) {
        return !filters.contains(hostname);
    }

    private boolean validContentState(int code) {
        return HttpURLConnection.HTTP_OK == code;
    }

    private boolean validFileType(String type) {
        return this.allowTypes.contains(type);
    }

    private boolean validFileSize(int size) {
        return size < this.maxSize;
    }
}
